/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
 */
#ifndef GADGETS_PROFILE_H_
#define GADGETS_PROFILE_H_

/**
 * @file
 * @defgroup gadgets_profile Alexa Gadgets profile
 * @{
 * @brief Alexa Gadgets profile API.
 *
 * @details Implements the Alexa Gadgets profile and data handling for
 *          protobuf-defined interfaces.
 *          These interfaces are protobuf-defined data formats for Directives
 *          (incoming data) and events (outgoing data).
 *          All the standard defined interfaces in the Alexa Gadgets Toolkit
 *          are handled.
 *
 *          Custom interfaces are also supported,
 *          including a basic custom event type.
 *
 *          To interact with Alexa, follow the registration
 *          steps outlined in the Alexa Gadgets documentation:
 *          https://developer.amazon.com/en-US/docs/alexa/alexa-gadgets-toolkit/understand-alexa-gadgets-toolkit.html
 */

#include <zephyr/types.h>

#if CONFIG_GADGETS_CAPABILITY_MUSICDATA_ENABLE
#include "alexaGadgetMusicDataTempoDirective.pb.h"
#include "alexaGadgetMusicDataTempoDirectivePayload.pb.h"
#endif
#if CONFIG_GADGETS_CAPABILITY_ALERTS_ENABLE
#include "alertsSetAlertDirective.pb.h"
#include "alertsSetAlertDirectivePayload.pb.h"
#include "alertsDeleteAlertDirective.pb.h"
#include "alertsDeleteAlertDirectivePayload.pb.h"
#endif
#if CONFIG_GADGETS_CAPABILITY_SPEECHDATA_ENABLE
#include "alexaGadgetSpeechDataSpeechmarksDirective.pb.h"
#include "alexaGadgetSpeechDataSpeechmarksDirectivePayload.pb.h"
#endif
#if CONFIG_GADGETS_CAPABILITY_STATELISTENER_ENABLE
#include "alexaGadgetStateListenerStateUpdateDirective.pb.h"
#include "alexaGadgetStateListenerStateUpdateDirectivePayload.pb.h"
#endif
#if CONFIG_GADGETS_CAPABILITY_NOTIFICATIONS_ENABLE
#include "notificationsSetIndicatorDirective.pb.h"
#include "notificationsSetIndicatorDirectivePayload.pb.h"
#include "notificationsClearIndicatorDirective.pb.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/** @brief Gadgets event types */
enum gadgets_evt_type {
	/** Handshake with peer completed */
	GADGETS_EVT_READY,

	/** SetAlert Directive */
	GADGETS_EVT_SETALERT,

	/** DeleteAlert Directive */
	GADGETS_EVT_DELETEALERT,

	/** SetIndicator Directive */
	GADGETS_EVT_SETINDICATOR,

	/** ClearIndicator Directive */
	GADGETS_EVT_CLEARINDICATOR,

	/** StateUpdate Directive */
	GADGETS_EVT_STATEUPDATE,

	/** Speechmarks Directive */
	GADGETS_EVT_SPEECHMARKS,

	/** Tempo Directive */
	GADGETS_EVT_MUSICTEMPO,

	/** Custom Directive */
	GADGETS_EVT_CUSTOM,

	/** Custom event sent */
	GADGETS_EVT_CUSTOM_SENT
};

/** @brief Gadgets event details */
struct gadgets_evt {
	enum gadgets_evt_type type;
	union {
		/* Note: these are the structs generated by protoc compiler,
		 * based on .proto files.
		 * Abstraction not added in order to reference original doc:
		 * https://developer.amazon.com/en-US/docs/alexa/alexa-gadgets-toolkit/defined-interfaces.html
		 */

#if CONFIG_GADGETS_CAPABILITY_NOTIFICATIONS_ENABLE
		/** Parameters for @ref GADGETS_EVT_SETINDICATOR */
		struct _notifications_SetIndicatorDirectivePayloadProto *set_indicator;
#endif

#if CONFIG_GADGETS_CAPABILITY_ALERTS_ENABLE
		/** Parameters for @ref GADGETS_EVT_SETALERT */
		struct _alerts_SetAlertDirectivePayloadProto *set_alert;

		/** Parameters for @ref GADGETS_EVT_DELETEALERT */
		struct _alerts_DeleteAlertDirectivePayloadProto *delete_alert;
#endif

#if CONFIG_GADGETS_CAPABILITY_STATELISTENER_ENABLE
		/** Parameters for @ref GADGETS_EVT_STATEUPDATE */
		struct _alexaGadgetStateListener_StateUpdateDirectivePayloadProto *state_update;
#endif

#if CONFIG_GADGETS_CAPABILITY_SPEECHDATA_ENABLE
		/** Parameters for @ref GADGETS_EVT_SPEECHMARKS */
		struct _alexaGadgetSpeechData_SpeechmarksDirectivePayloadProto *speech_marks;
#endif

#if CONFIG_GADGETS_CAPABILITY_MUSICDATA_ENABLE
		/** Parameters for @ref GADGETS_EVT_MUSICTEMPO */
		struct _alexaGadgetMusicData_TempoDirectivePayloadProto *music_tempo;
#endif

		/** Parameters for @ref GADGETS_EVT_CUSTOM */
		struct {
			const char *name;
			const void *payload;
			size_t size;
		} custom_directive;
	} parameters;
};

/** @brief Callback type for Gadget events. */
typedef void (*gadgets_profile_cb_t)(const struct gadgets_evt *evt);

/**@brief Initialize the profile.
 *
 * @details Initializes profile state and the underlying
 *          Gadgets Bluetooth Service.
 *
 * @param[in] evt_handler event handler function pointer.
 *
 * @retval 0 If initialization is successful.
 *           Otherwise, a negative value is returned.
 */
int gadgets_profile_init(gadgets_profile_cb_t evt_handler);

/**@brief Start advertising using the Gadgets advertisement format.
 *
 * @param[in] bondable_type Set to true if the "new bond" payload format should
 *            be used. False when reconnecting to bonded peer.
 *
 * @retval 0 If advertisement is successfully started.
 *           Otherwise, a negative value is returned.
 */
int gadgets_profile_adv_start(bool bondable_type);

/**@brief Send a custom event to Alexa using preconfigured custom event.
 *
 * @details Custom events are constructed using user-specified protobuf format.
 *          This function uses a simple custom event structure
 *          (@ref custom_event.proto) with a single string as the payload.
 *          The string must be valid JSON for the cloud side to accept it.
 *          The namespace for this custom event is given by
 *          @ref CONFIG_GADGETS_CAPABILITY_CUSTOM_NAMESPACE.
 *
 * @param[in] name Null-terminated event name string.
 * @param[in] json Null-terminated JSON string.
 *
 * @retval 0 When successful.
 *           Otherwise, a negative value is returned.
 */
int gadgets_profile_custom_event_json_send(uint8_t *name, uint8_t *json);


/**@brief Send a pre-encoded custom event to Alexa.
 *
 * @details Custom events are constructed using user-specified protobuf format.
 *          The user of this function must encode the data using the chosen
 *          protobuf format and pass the encoded buffer to this function
 *          (i.e. the output from pb_encode()).
 *          See here for more information:
 *          https://developer.amazon.com/en-US/docs/alexa/alexa-gadgets-toolkit/custom-interface.html#events
 *
 * @param[in] encoded_data Data encoded using pb_encode()
 * @param[in] len          Length in bytes of encoded data
 *
 * @retval 0 When successful.
 *           Otherwise, a negative value is returned.
 */
int gadgets_profile_custom_event_send(uint8_t *encoded_data, size_t len);

#ifdef __cplusplus
}
#endif

/**
 *@}
 */

#endif /* GADGETS_PROFILE_H_ */
